Python Tuples Reference

Table of contents

  1. Creation
  2. Basic Operations
  3. Unpacking
  4. Comparing
  5. Named Tuples

1. Creation


In [1]:
# Create a tuple directly
digits = (0, 1, 'two')
digits


Out[1]:
(0, 1, 'two')

In [2]:
# Create a tuple from a list
digits = tuple([0, 1, 'two'])
digits


Out[2]:
(0, 1, 'two')

In [3]:
# For a single item tuple, a trailing comma is required to tell the intepreter its a tuple
zero = (0,)
zero


Out[3]:
(0,)

2. Basic Operations


In [4]:
# elements of a tuple cannot be modified (this would throw an error)
# digits[2] = 2

In [5]:
#concatenate tuples
digits = digits + (3,4)
digits


Out[5]:
(0, 1, 'two', 3, 4)

In [6]:
# Create a single tuple with elements repeated (also workss with lists)
(3, 4) * 2


Out[6]:
(3, 4, 3, 4)

In [7]:
# sort a list of tuples
tens = [(20,60), (10,40), (20,30)]
sorted(tens) #sorts by first element in tuple, then second element


Out[7]:
[(10, 40), (20, 30), (20, 60)]

3. Unpacking


In [8]:
bart = ('male', 10, 'simpson') # create a tuple
(sex, age, surname) = bart
print(sex)
print(age)
print(surname)


male
10
simpson

In [9]:
#use the star expression to load multiple values into a list
record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
name, email, *phone_numbers = record
phone_numbers


Out[9]:
['773-555-1212', '847-555-1212']

In [10]:
# star expressions can be used in the middle of the iterable too!
def drop_first_last(grades):
    first, *middle, last = grades
    return float(sum(middle)) / len(middle)

drop_first_last([3, 8, 8, 8, 8, 8,8, 100])


Out[10]:
8.0

4. Comparing


In [11]:
# Tuples are compared by comparing their members in order
(3,9) < (5,3)


Out[11]:
True

In [12]:
(3,'banana') < (3,'apple')


Out[12]:
False

In [13]:
(3,'banana') == (3,'ban')


Out[13]:
False

In [14]:
# Tuple members are only compared if needed.
# Here is an uncomparable type
class mytype:
    def go():
        pass

a = mytype()
b = mytype()

(3, a) < (5,b)


Out[14]:
True

In [15]:
# but the folllowing code would generate an error because a and b would need to be evaluated

#(3,a) < (3,b)

5. Named Tuples

collections.namedtuple() is a factory method that returns a subclass of the standard Python tuple type. You feed it a type name, and the fields it should have, and it returns a class that you can instantiate, passing in values for the fields you’ve defined, and so on.


In [3]:
from collections import namedtuple
Subscriber = namedtuple('Subscriber', ['addr','joined']) # namedtuple(<tuple-name>, [field1, field2, field3...])
jonesy = Subscriber('jonesy@example.com','2012-10-19')
jonesy


Out[3]:
Subscriber(addr='jonesy@example.com', joined='2012-10-19')

In [4]:
len(jonesy)


Out[4]:
2

In [5]:
jonesy.addr


Out[5]:
'jonesy@example.com'

In [6]:
# because a namedtuple is a tuple it is immutable.  
# the following code would fail if uncommented

#jonesy.addr='another@example.com'

In [7]:
#instead, use replace()
jonesy = jonesy._replace(addr='another@example.com')
jonesy


Out[7]:
Subscriber(addr='another@example.com', joined='2012-10-19')

A subtle use of the _replace() method is that it can be a convenient way to populate named tuples that have optional or missing fields. To do this, you make a prototype tuple containing the default values and then use _replace() to create new instances with values replaced.


In [8]:
Stock = namedtuple('Stock', ['name', 'shares', 'price', 'date', 'time'])

# Create a prototype instance
stock_prototype = Stock('', 0, 0.0, None, None)

# Function to convert a dictionary to a Stock
def dict_to_stock(s):
    return stock_prototype._replace(**s)

a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
dict_to_stock(a)


Out[8]:
Stock(name='ACME', shares=100, price=123.45, date=None, time=None)

In [9]:
b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '12/17/2012'}
dict_to_stock(b)


Out[9]:
Stock(name='ACME', shares=100, price=123.45, date='12/17/2012', time=None)